#include "Jogo.hpp"
#include "Tabuleiro.hpp"
#include "Jogador.hpp"
#include <string>

using namespace jogodavelharedes;

    Jogo:: Jogo(Jogador* jogador1, Jogador* jogador2) {
        
        this->jogador1 = jogador1;
        this->jogador2 = jogador2;
        this->tabuleiro = new Tabuleiro(3, 3);
        this->vencedor = 0;
    }

    Jogo:: ~Jogo() {
        delete this->tabuleiro;
        
    }

    void Jogo:: iniciar() {
        this->vezDoJogador1 = true;
        this->contaJogadas = 0;
        this->fimDoJogo = false;
        this->vencedor = 0;
        this->tabuleiro->esvaziaTabuleiro();

    }

    Jogador* Jogo:: jogadorDaVez() {
        Jogador* jogadorDaVez = 0;

        if (this->vezDoJogador1) {
            jogadorDaVez = jogador1;
        }
        else {
            jogadorDaVez = jogador2;
        }
        return jogadorDaVez;

    }

    std::string* Jogo::performJogada() {
        if (!this->vezDoJogador1)
            return 0;   
    }

    bool Jogo:: ehJogadaValida(int linha, int coluna) {
        return ( linha >= 0 && linha <= 2 && coluna >= 0 && coluna <= 2 &&
                 this->tabuleiro->estaLivre(linha, coluna));

    }

    char Jogo:: fazerJogada(int linha, int coluna) {
        if(ehJogadaValida(linha, coluna)) {
            //pega o simbolo do jogador da vez "X ou O"
            char simbolo = jogadorDaVez()->getSimbolo();

            //coloca o simbolo do jogador da vez no tabuleiro
            tabuleiro->setPeca(linha, coluna, simbolo);
            contaJogadas++;

            if(!verificaFimDoJogo()) { //muda de jogador
                vezDoJogador1 = !vezDoJogador1; //jogador 2 joga
            }
            else {
                this->fimDoJogo = true;
                if(this->vencedor != 0) { //empate
                    this->vencedor->incrementaPontuacao();
                }
            }
            
            return simbolo; //retorna o simbolo do jogador
        }

        return ' ';
    }

    void Jogo:: verificaVencedor() {
        if (this->vezDoJogador1) {
            this->vencedor = this->jogador1;
        }
        else {
            this->vencedor = this->jogador2;
        }
    }

    bool Jogo:: verificaFimDoJogo() {

        if (this->contaJogadas >= 5) {
            int linha;
            int coluna;
            char c1, c2, c3;

            //Verifica em linha
            coluna = 0;
            for (linha = 0; linha < 3; linha++) {
                c1 = tabuleiro->getPeca(linha, coluna);
                c2 = tabuleiro->getPeca(linha, coluna + 1);
                c3 = tabuleiro->getPeca(linha, coluna + 2);

                if ((c1 == c2) && (c1 == c3) && (c1 != ' ')) {
                    this->verificaVencedor();
                    return true;
                }
            }

            //Verifica em coluna
            linha = 0;
            for (coluna = 0; coluna < 3; coluna++) {
                c1 = tabuleiro->getPeca(linha, coluna);
                c2 = tabuleiro->getPeca(linha + 1, coluna);
                c3 = tabuleiro->getPeca(linha + 2, coluna);

                if ((c1 == c2) && (c1 == c3) && (c1 != ' ')) {
                    this->verificaVencedor();
                    return true;
                }
            }

            //Verifica em diagonal
            linha = 0;
            for (coluna = 0; coluna < 3; coluna++) {
                c1 = tabuleiro->getPeca(linha, coluna);
                c2 = tabuleiro->getPeca(linha + 1, coluna + 1);
                c3 = tabuleiro->getPeca(linha + 2, coluna + 2);

                if ((c1 == c2) && (c1 == c3) && (c1 != ' ')) {
                    this->verificaVencedor();
                    return true;
                }
            }

                linha = 0;
                coluna = 0;
                c1 = tabuleiro->getPeca(linha, coluna + 2);
                c2 = tabuleiro->getPeca(linha + 1, coluna + 1);
                c3 = tabuleiro->getPeca(linha + 2, coluna);

                if ((c1 == c2) && (c1 == c3) && (c1 != ' ')) {
                    this->verificaVencedor();
                    return true;
                }

                if (this->contaJogadas == 9) {
                    contaEmpates++;
                    return true;
                }
            }
        return false;
        
    }

    void Jogo:: zeraEmpates() {
        contaEmpates = 0;

    }

    bool Jogo:: isFimDoJogo() {
        return fimDoJogo;
        
    }

    Jogador* Jogo:: getVencedor() {
        return vencedor;

    }

    Tabuleiro* Jogo:: getTabuleiro() {
        return this->tabuleiro;

    }

    Jogador* Jogo:: getJogador1() {
        return jogador1;

    }

    Jogador* Jogo:: getJogador2() {
        return jogador2;

    }

    int Jogo:: getContaEmpates() {
        return contaEmpates;
        
    }

    bool Jogo:: houveVencedor() {

        return this->vencedor != 0;
    }

